﻿/**
*    Copyright (C) 2008  Chase Kernan 
*    chase.kernan@gmail.com
*
*    This program is free software: you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation, either version 3 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
* 
**/

package com.chasekernan.hxnova.componenteditor;
 
import com.chasekernan.hxnova.core.components.ComponentSet;
import org.aswing.border.EmptyBorder;
import org.aswing.geom.IntRectangle;
import org.aswing.Insets;
import org.aswing.JButton;
import org.aswing.JComboBox;
import org.aswing.JFrame;
import com.chasekernan.hxnova.core.components.Hull;
import flash.display.DisplayObject;
import org.aswing.JLoadPane;
import org.aswing.JPanel;
import org.aswing.JTable;
import flash.display.Loader;
import flash.net.URLRequest;
import org.aswing.geom.IntDimension;
import flash.events.Event;
import flash.events.IOErrorEvent;
import org.aswing.JOptionPane;
import org.aswing.SoftBox;
import org.aswing.VectorListModel;

/**
    Contains a table of all of the hull parts, a background image and a drag 
    and drop facility for the actual design.
**/
class HullEditor extends JFrame {
    
    public static var DEFAULT_SIZE = new IntDimension(700, 550);
	public static var DEFAULT_IMAGE_SIZE = new IntDimension(690, 500);
    
    private var backgroundImage : JLoadPane;
    private var hullParts : Array<HullPartEditor>;
    private var storageSpaces : Array<StorageSpaceEditor>;
    private var hull : Hull;
	private var box : SoftBox;
	private var addButtonsPanel : JPanel;
	private var typesBox : JComboBox;
	private var addComponentButton : JButton;
	private var addStorageButton : JButton;
	private var editComponentTypesButton : JButton;
    
    /**
        Creates a new HullEditor and attempts to load the background image 
        specified by the hull.
    **/
	public function new(parent : Dynamic, editedHull : Hull) {
		super(parent, "Hull Editor", true);
		
		if (editedHull == null) throw "Hull cannot be null.";
        hull = editedHull;
		
		storageSpaces = new Array();
		hullParts = new Array();
		
		setPreferredWidth(DEFAULT_SIZE.width);
		setWidth(DEFAULT_SIZE.width);
		
		box = SoftBox.createVerticalBox(5);
		box.setBorder(new EmptyBorder(null, new Insets(5, 5, 5, 5)));
        
		//---background image---
		backgroundImage = new JLoadPane(hull.backgroundPic);	
		
		var me = this;
		backgroundImage.addEventListener(IOErrorEvent.IO_ERROR, 
		function(?e : Dynamic) {
			JOptionPane.showMessageDialog("Error", 
										  "Couldn't load background image.");
			me.backgroundImage.setPreferredSize(DEFAULT_IMAGE_SIZE);
			me.backgroundImage.setSize(DEFAULT_IMAGE_SIZE);
			
			me.loadFromHull();
		});
		
		
		backgroundImage.addEventListener(Event.COMPLETE, 
		function(?e : Dynamic) {
			var h = Std.int(me.backgroundImage.getLoader().content.height) + 
					21;
			me.setHeight(h);
			me.setPreferredHeight(h);
			
			var w = Std.int(me.backgroundImage.getLoader().content.width) + 20;
			me.setPreferredWidth(w);
			me.setWidth(w);
			
			me.loadFromHull();
		});
		
		if (backgroundImage != null) {
			box.append(backgroundImage);
		}
		
		//---buttons on bottom ---
		addButtonsPanel = new JPanel();
		
		editComponentTypesButton = new JButton("Edit Type Sets");
		editComponentTypesButton.addActionListener(onClickEditComponentTypes);
		
		addComponentButton = new JButton("Add Component");
		addComponentButton.addActionListener(addComponentObject);
		
		addStorageButton = new JButton("Add Storage");
		addStorageButton.addActionListener(addStorageObject);
		
		typesBox = new JComboBox(["Weapon"]);
		typesBox.setPreferredWidth(100);
		typesBox.setWidth(100);
		typesBox.setSelectedIndex(0);
		updateTypesBox();
		
		addButtonsPanel.appendAll(editComponentTypesButton,
								  typesBox,
								  addComponentButton, 
								  addStorageButton);
		box.append(addButtonsPanel);
		
		setContentPane(box);
		
		//in case picture isn't loaded
		setPreferredHeight(600);
		setHeight(600);
		
		addEventListener(Event.ENTER_FRAME, onEnterFrame);
	}
	
	private function loadFromHull() {
		for (hullPart in hull.parts) {
			var editor = new HullPartEditor(this, hullPart, getIntBounds());
			addListenerToObject(editor);
			hullParts.push(editor);
		}
		
		for (storage in hull.storage) {
			var editor = new StorageSpaceEditor(this, storage, 
													  getIntBounds());
			addListenerToObject(editor);
			storageSpaces.push(editor);
		}
	}
	
	private function onClickEditComponentTypes(?e : Dynamic) {
        var editWindow = new EditComponentTypeSets();
		
		var me = this; //needed to access members
		editWindow.addEventListener(EditComponentTypeSets.CLOSE, 
		function(?e : Dynamic) {
			me.updateTypesBox();
		});
		
        editWindow.show();
    }
	
	private function updateTypesBox() {
		var types = new Array<String>();
		for (type in ComponentSet.COMPONENT_TYPE_SETS) types.push(type.name);
		typesBox.setListData(types);
		typesBox.getPopupList().updateListView();
	}
	
	private function addStorageObject(?e : Dynamic) {
		var editor = new StorageSpaceEditor(this, 
				StorageSpaceEditor.createStorageSpace(),
				getIntBounds());
		
		hull.storage.push(editor.getObject());
		storageSpaces.push(editor);
		addListenerToObject(editor);
	}
	
	private function addListenerToObject(obj : HullEditorObject<Dynamic>) {
		obj.addEventListener(CloseEvent.CLOSE, removeObject);
	}
	
	private function removeObject(e : Dynamic) {
		if (e.isPartEditor()) {
			hullParts.remove(e.object);
			hull.parts.remove(e.object.data);
		} else {
			storageSpaces.remove(e.object);
			hull.storage.remove(e.object.data);
		}
	}
	
	private function getIntBounds() : IntRectangle {
		var bounds = new IntRectangle();
		bounds.setSize(backgroundImage.getSize());
		bounds.setLocation(getLocation());
		
		return bounds;
	}
	
	private function addComponentObject(?e : Dynamic) {
		try {
			var type = ComponentSet.getComponentTypeSetByName(
					typesBox.getSelectedItem());
			var editor = new HullPartEditor(this, 
					HullPartEditor.createHullPart(type),
					getIntBounds());
					
			hull.parts.push(editor.getObject());
			hullParts.push(editor);
			
			addListenerToObject(editor);
		} catch (e : Dynamic) {}
	}
	
	private function onEnterFrame(?e : Dynamic) {
		var bounds = getIntBounds();
		
		for (part in hullParts) part.checkBoundsAndSave(bounds);
		for (storage in storageSpaces) storage.checkBoundsAndSave(bounds);
	}
}